﻿#include "CVlcRtspOper.h"
#include "CHeader.h"
#include <QThread>
#include <QPainter>
#include <QCoreApplication>
#include <QtConcurrent/QtConcurrentRun>

CVlcRtspOper::CVlcRtspOper(CDevDataCam *pDevDataCam,const QString &url, QWidget *pWidget)
	:m_pVlcInstance(nullptr),
	m_pMediaPlayer(nullptr),
	m_pMedia(nullptr)
{
	m_pCurrentFrame = new QImage(pWidget->width(), pWidget->height(), QImage::Format_RGB32);
	m_pDevDataCam = pDevDataCam;
	m_nWidth = pWidget->width();
	m_nHeight = pWidget->height();
	m_bInit = false;
	m_bThread = false;
	QLabel* label = qobject_cast<QLabel*>(pWidget);
	m_pImageLabel = QPointer<QLabel>(label);
	m_sUrl = url;
	m_nResizeIndex = 0;
	init();
}
CVlcRtspOper::~CVlcRtspOper()
{
	if (m_pCurrentFrame != nullptr)
	{
		delete m_pCurrentFrame;
	}
	m_pCurrentFrame = nullptr;
	if (m_pMediaPlayer) 
	{
		libvlc_media_player_stop(m_pMediaPlayer);
		libvlc_media_player_release(m_pMediaPlayer);
	}
	if (m_pMedia) 
	{
		libvlc_media_release(m_pMedia);
	}
}

bool CVlcRtspOper::startCapture()
{
	if (!m_bInit)
	{
		return false;
	}
	if (m_pMediaPlayer == nullptr)
	{
		return false;
	}
	libvlc_media_player_play(m_pMediaPlayer);
	m_pFrameTimer = new QTimer();
	connect(m_pFrameTimer, &QTimer::timeout, m_pFrameTimer, [this]() 
		{
		// 通过 invokeMethod 强制主线程执行
		QMetaObject::invokeMethod(QCoreApplication::instance(), [this]() 
			{
			this->slot_CaptureFrame(); // 主线程执行
			}, Qt::QueuedConnection);
		});
	m_pFrameTimer->moveToThread(QCoreApplication::instance()->thread()); // 主线程事件循环
	m_pFrameTimer->start(50);
	if (!m_bThread)
	{
		m_bThread = true;
		startThreadTask();
	}
	
	return true;
}

bool CVlcRtspOper::stopCapture()
{
	disconnect(m_pFrameTimer, nullptr, this, nullptr);
	m_pFrameTimer->stop();
	while (m_bTimer)
	{
		QEventLoop loop;
		QTimer::singleShot(10, &loop, SLOT(quit()));
		loop.exec();
	}
	m_bThread = false;
	QThread::msleep(50);
	libvlc_media_player_set_pause(m_pMediaPlayer, 1);
	libvlc_media_player_stop(m_pMediaPlayer);
	libvlc_media_player_release(m_pMediaPlayer);
	m_pMediaPlayer = nullptr;
	return true;
}

void CVlcRtspOper::setRollerNum(int nNum, int nBologn, QString sRollerDesc)
{
	m_cRollerLock.lock();
	m_sRollerDesc = sRollerDesc;
	m_nRollerNum = nNum;
	m_nBelogn = nBologn;
	m_cRollerLock.unlock();
}

bool CVlcRtspOper::init()
{
	if (m_bInit)
	{
		return true;
	}
	// 初始化 VLC 实例
	m_pVlcInstance = libvlc_new(0, NULL);
	if (!m_pVlcInstance) 
	{
		return false;
	}
	// 创建媒体
	m_pMedia = libvlc_media_new_location(m_pVlcInstance, m_sUrl.toStdString().c_str());
	if (!m_pMedia) 
	{
		return false;
	}
	// 创建媒体播放器
	m_pMediaPlayer = libvlc_media_player_new_from_media(m_pMedia);
	if (!m_pMediaPlayer) 
	{
		return false;
	}
	// 设置回调
	libvlc_video_set_callbacks(m_pMediaPlayer, lockCallback, unlockCallback, nullptr, this);
	m_cImageLock.lock();
	libvlc_video_set_format(m_pMediaPlayer, "RV32", m_pCurrentFrame->width(), m_pCurrentFrame->height(), m_pCurrentFrame->bytesPerLine());
	m_cImageLock.unlock();
	m_bInit = true;
	return true;
}

bool CVlcRtspOper::initMainThread()
{
	return false;
}

void CVlcRtspOper::drawRoller()
{
	QString sDesc = "";
	m_cRollerLock.lock();
	sDesc = m_sRollerDesc;
	m_cRollerLock.unlock();
	QPainter painter(&m_cDrawFrame);
	int nW = m_cDrawFrame.width();
	int nH = m_cDrawFrame.height();
	QRect rect(nW*0.7, 10, nW*0.2, nH*0.2);

	// 设置文字背景为透明
	painter.setBackgroundMode(Qt::TransparentMode);
	// 绘制 "96号" 使用 16 号加粗字体
	QFont font16("SimSun", nH*0.06, QFont::Bold); // 16号加粗宋体
	painter.setFont(font16);
	painter.setPen(Qt::green);
	QRect textRect1(rect.left(), rect.top() + 10, rect.width(), nH*0.15); // 上半部分用于 "96号"
	painter.drawText(textRect1, Qt::AlignCenter, sDesc);
	// 绘制 "托辊" 使用 12 号加粗字体
	QFont font12("SimSun", nH*0.06, QFont::Bold); // 12号加粗宋体
	painter.setFont(font12);
	QRect textRect2(rect.left(), textRect1.bottom(), rect.width(), nH*0.12); // 下半部分用于 "托辊"
	painter.drawText(textRect2, Qt::AlignCenter, A2T("托辊"));
}

void CVlcRtspOper::startThreadTask()
{
	QtConcurrent::run([=]() 
	{
		while (m_bThread)
		{
			m_cImageLock.lock();
			if (m_pCurrentFrame !=nullptr)
			{
				m_cDrawFrame = m_pCurrentFrame->scaled(m_nWidth, m_nHeight, Qt::IgnoreAspectRatio, Qt::FastTransformation);
			}	
			m_cImageLock.unlock();
			QThread::msleep(30);
		}	
	});
}

void CVlcRtspOper::drawRollerRealign()
{
	// 获取客户区的宽度和高度
	int clientWidth = m_cDrawFrame.width();;
	int clientHeight= m_cDrawFrame.height();
	QPainter painter(&m_cDrawFrame);

	// 根据状态选择画笔
	QPen leftPen = getPenForRectifyValue(m_dLeftRectifyValue, m_nRectifySetValueTwo, m_nRectifySetValue,m_nIsHaveBeltState);
	QPen rightPen = getPenForRectifyValue(m_dRightRectifyValue, m_nRectifySetValueTwo, m_nRectifySetValue, m_nIsHaveBeltState);

	// 画第一条线
	painter.setPen(leftPen);
	painter.drawLine(
		m_BeltEdgePf1.x() * clientWidth / 1920, m_BeltEdgePf1.y() * clientHeight / 1080,
		m_BeltEdgePf4.x() * clientWidth / 1920, m_BeltEdgePf4.y() * clientHeight / 1080
	);

	// 画第二条线
	painter.setPen(rightPen);
	painter.drawLine(
		m_BeltEdgePf2.x() * clientWidth / 1920, m_BeltEdgePf2.y() * clientHeight / 1080,
		m_BeltEdgePf3.x() * clientWidth / 1920, m_BeltEdgePf3.y() * clientHeight / 1080
	);

	// 设置文本颜色
	painter.setFont(QFont("SimSun", clientHeight*0.03, QFont::Bold));

	// 绘制左偏值文本
	QString strLeftValue = QString(A2T("左偏: %1 mm").arg(m_dLeftRectifyValue * 10, 0, 'f', 1));
	painter.setPen(leftPen);
	QRect rectLeftText(10, clientHeight*0.8, 300, 50);
	painter.drawText(rectLeftText, Qt::AlignLeft | Qt::AlignVCenter, strLeftValue);

	// 绘制右偏值文本
	QString strRightValue = QString(A2T("右偏: %1 mm").arg(m_dRightRectifyValue * 10, 0, 'f', 1));
	painter.setPen(rightPen);
	QRect rectRightText(10, clientHeight*0.9, 300, 50);
	painter.drawText(rectRightText, Qt::AlignLeft | Qt::AlignVCenter, strRightValue);
}

QPen CVlcRtspOper::getPenForRectifyValue(double rectifyValue, double setValueTwo, double setValue ,int m_nHaveBeltState)
{
	// 设置画笔
	QPen greenPen(Qt::green,4);
	QPen redPen(Qt::red, 4);
	QPen yellowPen(Qt::yellow, 4);
	QPen grayPen(Qt::gray, 4);

	if (m_nIsHaveBeltState != 0)
	{
		if (!m_bBeltState)
		{
			return grayPen;
		}
	}
	if (rectifyValue <= setValueTwo)
	{
		return redPen;
	}
	else if (rectifyValue > setValueTwo && rectifyValue <= setValue)
	{
		return yellowPen;
	}
	else
	{
		return greenPen;
	}
}


void * CVlcRtspOper::lockCallback(void * opaque, void ** planes)
{
	auto *self = static_cast<CVlcRtspOper *>(opaque);
	self->m_cImageLock.lock();
	if (self->m_pCurrentFrame != nullptr)
	{
		*planes = self->m_pCurrentFrame->bits();
	}
	return nullptr;
}

void CVlcRtspOper::unlockCallback(void * opaque, void * picture, void * const * planes)
{
	auto *self = static_cast<CVlcRtspOper *>(opaque);
	Q_UNUSED(opaque);
	Q_UNUSED(picture);
	Q_UNUSED(planes);
	self->m_cImageLock.unlock();
}



void CVlcRtspOper::slot_CaptureFrame()
{
	m_bTimer = true;
	qDebug() << "this =" << this;
	qDebug() << "m_pImageLabel address =" << &m_pImageLabel;
	qDebug() << "m_pImageLabel value =" << m_pImageLabel;
	if (m_pImageLabel == nullptr)
	{
		m_bTimer = false;
		return;
	}
	if (m_nResizeIndex > 20)
	{
		m_nWidth = m_pImageLabel->width();
		m_nHeight = m_pImageLabel->height();
		m_nResizeIndex = 0;
	}
	m_nResizeIndex++;
	if (m_nDrawType == 0)
	{
		//drawRoller();
	}
	else if (m_nDrawType == 1)
	{
		drawRollerRealign();
	}
	// 将结果显示到 QLabel
	if (m_cImageLock.tryLock(1))
	{
		if (!m_cDrawFrame.isNull()) 
		{
			m_pImageLabel->setPixmap(QPixmap::fromImage(m_cDrawFrame));
		}
		m_cImageLock.unlock();
		m_pImageLabel->update();
	}
	m_bTimer = false;;
	
}


void CVlcRtspOper::setCorrectData(double dLeftRectifyValue, double dRightRectifyValue, int nRectifySetValue, int nRectifySetValueTwo, QPointF BeltEdgePf1, QPointF BeltEdgePf2, QPointF BeltEdgePf3, QPointF BeltEdgePf4, int nIsHaveBeltState, bool bBeltState, int nDrawType)
{
	m_dLeftRectifyValue = dLeftRectifyValue;
	m_dRightRectifyValue = dRightRectifyValue;
	m_nRectifySetValue = nRectifySetValue;
	m_nRectifySetValueTwo = nRectifySetValueTwo;
	m_BeltEdgePf1 = BeltEdgePf1;
	m_BeltEdgePf2 = BeltEdgePf2;
	m_BeltEdgePf3 = BeltEdgePf3;
	m_BeltEdgePf4 = BeltEdgePf4;
	m_nIsHaveBeltState = nIsHaveBeltState;
	m_bBeltState = bBeltState;
	m_nDrawType = nDrawType;
}